#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <pthread.h>
#include <cerrno>

const int MAX_NUMBER_OF_STATION=2;

struct SockInfo {
    int fd;
    pthread_t tid;
    struct sockaddr_in addr;
};

struct SockInfo infos[MAX_NUMBER_OF_STATION];

using namespace std;

void *pthmain(void *arg)
{
    char buf[1024];
    pthread_mutex_t mutex_collect;
    int client_fd=(int)(long)arg;
    while(1){
        pthread_mutex_lock(&mutex_collect);
        int n = read(client_fd, buf, sizeof(buf)-1);
        if (n < 0) {
            cerr << "Failed to read data from client\n";
        } else if (n == 0) {
            cout << "Client closed the connection\n";
        } else {
            buf[n] = '\0';
            cout<<"ip:"<<inet_ntoa(infos->addr.sin_addr)<<endl;
            cout<<client_fd << " Received data: " << buf << "\n";

            // do something with the JSON data here...
            sleep(3);
        }
        pthread_mutex_unlock(&mutex_collect);
    }
}

int main()
{
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

    int server_fd, client_fd;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_addr_len;

    // create a TCP socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);

    //fcntl(server_fd,F_SETFL,O_NONBLOCK);

    if (server_fd < 0) {
        cerr << "Failed to create socket\n";
        return -1;
    }

    // bind to a specific IP address and port
    server_addr.sin_family = AF_INET;

    //202 outside
    //230 room

    //server_addr.sin_addr.s_addr = inet_addr("192.168.1.231"); // bind to a specific IP address
    server_addr.sin_addr.s_addr = inet_addr("192.168.1.231");
    server_addr.sin_port = htons(33345); //230 use
//    server_addr.sin_port = htons(33345);// 202 use
    //client_addr.sin_addr.s_addr = inet_addr("192.168.1.230");

//    client_addr.sin_addr.s_addr = inet_addr("192.168.1.202");
//    client_addr.sin_port = htons(33345);

    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        cerr << "Failed to bind to port\n";
        return -1;
    }

    // listen for incoming connections
    if (listen(server_fd, 5) < 0) {
        cerr << "Failed to listen for connections\n";
        return -1;
    }

    cout << "Waiting for connections...\n";
    client_addr_len= sizeof(client_addr);
    for(int i=0;i<MAX_NUMBER_OF_STATION;i++){
        bzero(&infos[i],sizeof(infos[i]));
        infos[i].fd=-1;
        infos[i].tid=-1;
    }
    while (1) {

        struct SockInfo* pinfo;
        int tmp_i=0;
        if(tmp_i!=MAX_NUMBER_OF_STATION-1){
            for (int i = 0; i < MAX_NUMBER_OF_STATION; i++) {
                if (infos[i].fd == -1) {
                    pinfo = &infos[i];
                    break;
                }
                if (i == MAX_NUMBER_OF_STATION - 1) {
                    i--;
                }
                tmp_i = i;
            }
        }
        // accept a new connection
        client_fd = accept(server_fd, (struct sockaddr *)&pinfo->addr, &client_addr_len);
        if (client_fd < 0) {
            cerr << "Failed to accept connection\n";
            cerr<<::strerror(errno)<<endl;
            continue;
        }

        cout << "Accepted connection from " << inet_ntoa(client_addr.sin_addr) << "\n";

        pinfo->fd=client_fd;

        //创建线程

        int ret= pthread_create(&pinfo->tid,&attr,pthmain,(void*)(long)client_fd);
        pthread_detach(pinfo->tid);
    }

    close(server_fd);

    return 0;
}


